module SingleCycleDatapath(Clk, RegDst, Jump, Branch, MemtoReg, MemWrite, ALUSrc, RegWrite, Instruction31_26, Instruction5_0, RESET, ALUOperation         , M0, M1, M5, M16, M17); //Ms for test
	input Clk, RegDst, Jump, Branch, MemtoReg, MemWrite, ALUSrc, RegWrite, RESET;
	input [2:0] ALUOperation;
	output [5:0] Instruction31_26, Instruction5_0;
	
	output [7:0] M0, M1, M5, M16, M17; //for test
	
	wire [31:0] Instruction;
	wire [31:0] CurrentPC, NewPC, PCPlus4, PCAfterBeq, PCNoJump, JumpAddress;
	wire [31:0] ExtendedImm;
	
	wire[4:0] WriteRegister;
	wire [7:0] WriteData, Data1, Data2, ALUInB, ALUResult, DMEMData;
	wire Zero;
	
	
	//PC modules begin
	register_customsize #(32) PC(.D(NewPC), .C(Clk), .Q(CurrentPC), .RESET(RESET));
	
	//Instruction Memory
	IMEM InstructionMemory(.iClk(Clk), .iWe(1'b0), .iAddr(CurrentPC[7:2]), .iWdata(32'b0), .oRdata(Instruction));

	RCA_32bit PCAdder4(.A(CurrentPC), .B(32'd4), .Cin(1'b0), .S(PCPlus4), .Cout());
	
	SignExtend16to32 SignExtend(.I(Instruction[15:0]), .O(ExtendedImm));
	
	RCA_32bit PCImmAdder(.A(PCPlus4), .B(ExtendedImm<<2), .Cin(1'b0), .S(PCAfterBeq), .Cout()); //버그 가능성 의심 (.B())
	
	MUX_2to1 #(32) PCPlus4_Or_PCAfterBeq(.D0(PCPlus4), .D1(PCAfterBeq), .S0(Branch&Zero), .Y(PCNoJump));
	
	assign JumpAddress={PCPlus4[31:28], Instruction[25:0]<<2};
	
	MUX_2to1 #(32) PCNoJump_Or_JumpAddress(.D0(PCNoJump), .D1(JumpAddress), .S0(Jump), .Y(NewPC));
	//PC modules end
	
	MUX_2to1 #(5) WhichToWrite(.D0(Instruction[20:16]), .D1(Instruction[15:11]), .S0(RegDst), .Y(WriteRegister));
	
	//Register File
	RF RegisterFile(.Read1(Instruction[25:21]), .Read2(Instruction[20:16]), .Data1(Data1), .Data2(Data2), .Write(WriteRegister), .WriteData(WriteData), .RegWrite(RegWrite), .Clk(Clk), .RESET(RESET));
	
	MUX_2to1 #(8) ALUIn_Select(.D0(Data2), .D1(ExtendedImm[7:0]), .S0(ALUSrc), .Y(ALUInB));
	
	//ALU
	top ALU(.z(ALUResult), .alu(ALUOperation), .x(Data1), .y(ALUInB), .zero(Zero));
	
	//Data Memory
	DMEM DataMemory(.iClk(Clk), .iWe(MemWrite), .iAddr(ALUResult), .iWdata(Data2), .oRdata(DMEMData)
	, .M0(M0), .M1(M1), .M5(M5), .M16(M16), .M17(M17) //for test
	);
	
	MUX_2to1 #(8) WriteData_Select(.D0(ALUResult), .D1(DMEMData), .S0(MemtoReg), .Y(WriteData));
	
	
	assign Instruction31_26=Instruction[31:26];
	assign Instruction5_0=Instruction[5:0];
	
endmodule